/**
 * @File		: QuestionBankWindow.java
 * @Subject		: Allows the user to select the question bank to load
 * @author 		: Isaac Parenteau	locus2k@gmail.com
 * @Date		: October 12th, 2011
 * @Licence		: Licensed under the GPU LGPL
 */
package mil.cdc.windows;

import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import mil.cdc.listeners.CustomMouseListener;
import mil.cdc.main.Main;
import mil.cdc.utils.CDCConstants;
import mil.cdc.utils.Question;

import org.dyno.visual.swing.layouts.Bilateral;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;

//VS4E -- DO NOT REMOVE THIS LINE!
public class QuestionBankWindow extends JFrame {

	private static final long serialVersionUID = 1L;
	private JLabel testLbl;
	private JList testList;
	private JScrollPane jScrollPane0;
	private JLabel numLbl;
	private JTextField numTextField;
	private JComboBox questionComboBox;
	private JLabel questionLbl;
	private JComboBox volumeComboBox;
	private JLabel volumeLbl;
	private JButton okBtn;
	private JButton cancelBtn;
	private JFileChooser fc;
	
	private ArrayList<Question> questions;
	private String selectedCDC = "";
	private int numOfQuestions = 0;
	private int selectedQuestion = 0;
	private Random rng = new Random();
	private int lineNumber = 0;
	private boolean volume = false;
	private String begVol = "";
	private String endVol = "";
	private MainWindow mainWindow = null;
	private File file = null;
	
	
	public QuestionBankWindow() {
		initComponents();
	}

	private void initComponents() {
		setTitle("Question Bank");
		setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/mil/cdc/data/ico/af.gif")));
		setLayout(new GroupLayout());
		add(getTesLbl(), new Constraints(new Leading(12, 12, 12), new Leading(6, 10, 10)));
		add(getVolumeComboBox(), new Constraints(new Bilateral(150, 12, 60), new Leading(236, 12, 12)));
		add(getJScrollPane0(), new Constraints(new Bilateral(11, 12, 22), new Leading(27, 135, 12, 12)));
		add(getNumLbl(), new Constraints(new Leading(12, 12, 12), new Leading(168, 12, 12)));
		add(getNumTextField(), new Constraints(new Bilateral(151, 12, 4), new Leading(168, 12, 12)));
		add(getQuestionComboBox(), new Constraints(new Bilateral(150, 12, 60), new Leading(200, 12, 12)));
		add(getQuestionLbl(), new Constraints(new Leading(32, 127, 127), new Leading(206, 12, 12)));
		add(getVolumeLbl(), new Constraints(new Leading(50, 119, 119), new Leading(240, 12, 12)));
		add(getOkBtn(), new Constraints(new Leading(51, 82, 12, 12), new Leading(291, 10, 10)));
		add(getCancelBtn(), new Constraints(new Leading(148, 83, 10, 10), new Leading(291, 12, 12)));
		getFc();
		setResizable(false);
		setSize(300, 362);
		setVisible(true);
	}

	private void getFc() {
		fc = new JFileChooser();
		
	}

	private JButton getCancelBtn() {
		if (cancelBtn == null) {
			cancelBtn = new JButton();
			cancelBtn.setText("Cancel");
			cancelBtn.addMouseListener(new CustomMouseListener(this, CDCConstants.CLOSE));
		}
		return cancelBtn;
	}
	
	private JButton getOkBtn() {
		if (okBtn == null) {
			okBtn = new JButton();
			okBtn.setText("Ok");
			okBtn.addMouseListener(new CustomMouseListener(this, CDCConstants.SUBMIT));
		}
		return okBtn;
	}

	private JLabel getVolumeLbl() {
		if (volumeLbl == null) {
			volumeLbl = new JLabel();
			volumeLbl.setText("Which Volume:");
		}
		return volumeLbl;
	}

	private JComboBox getVolumeComboBox() {
		if (volumeComboBox == null) {
			volumeComboBox = new JComboBox();
			volumeComboBox.setModel(new DefaultComboBoxModel(new Object[] { "All Volumes",
					"Volume 1", "Volume 2", "Volume 3", "Volume 4", "Volume 5"}));
			volumeComboBox.setDoubleBuffered(false);
			volumeComboBox.setBorder(null);
		}
		return volumeComboBox;
	}

	private JLabel getQuestionLbl() {
		if (questionLbl == null) {
			questionLbl = new JLabel();
			questionLbl.setText("Which Questions:");
		}
		return questionLbl;
	}

	private JComboBox getQuestionComboBox() {
		if (questionComboBox == null) {
			questionComboBox = new JComboBox();
			questionComboBox.setModel(new DefaultComboBoxModel(new Object[] { "All Questions",
					"Only Test Questions", "Only Review Questions"}));
			questionComboBox.setDoubleBuffered(false);
			questionComboBox.setBorder(null);
		}
		return questionComboBox;
	}

	private JTextField getNumTextField() {
		if (numTextField == null) {
			numTextField = new JTextField();
		}
		return numTextField;
	}

	private JLabel getNumLbl() {
		if (numLbl == null) {
			numLbl = new JLabel();
			numLbl.setText("Number of Questions:");
		}
		return numLbl;
	}

	private JScrollPane getJScrollPane0() {
		if (jScrollPane0 == null) {
			jScrollPane0 = new JScrollPane();
			jScrollPane0.setViewportView(getTestList());
		}
		return jScrollPane0;
	}

	private JList getTestList() {
		if (testList == null) {
			testList = new JList();
			DefaultListModel listModel = new DefaultListModel();
			addTests(listModel);
			testList.setModel(listModel);
			testList.addListSelectionListener(new ListSelectionListener() {
				
				@Override
				public void valueChanged(ListSelectionEvent arg0) {
					selectedCDC = (String)testList.getSelectedValue();
		            Main.debugWindow.addMessage("Selected Test: " + selectedCDC);
		            getVolumes();
					
				}
			});
			testList.setSelectedIndex(0);
		}
		return testList;
	}

	private void addTests(DefaultListModel listModel) {
		listModel.addElement("2A353");
		listModel.addElement("Custom Test");
	}

	private JLabel getTesLbl() {
		if (testLbl == null) {
			testLbl = new JLabel();
			testLbl.setText("Select Desired Test");
		}
		return testLbl;
	}
	
	public void attachToMainWindow(MainWindow mainWindow) {
		this.mainWindow = mainWindow;
	}
	
	public void loadQuestions() {
		if (mainWindow == null) {
			Main.debugWindow.addMessage("Question Bank was not attached to the main Window");
			Main.errorWindow.displayErrorMessage("Unable to start the program");
			Main.close();
			dispose();
		}
		
		selectedCDC = (String)testList.getSelectedValue();
		
		Main.debugWindow.addMessage("Selected CDC: " + selectedCDC);
		
		String value = numTextField.getText().trim().equals("") ? "0" : 
			numTextField.getText().trim();
		
		try {
			numOfQuestions = Integer.parseInt(value);
		} catch (NumberFormatException ex) {
			Main.errorWindow.displayErrorMessage("Must Enter Numerical Number");
			Main.debugWindow.addMessage("Must Enter Numerical Number");
		}
		
		selectedQuestion = questionComboBox.getSelectedIndex();
		
		begVol = String.format("[volume%s]", volumeComboBox.getSelectedIndex());
		endVol = String.format("[endvolume%s]", volumeComboBox.getSelectedIndex());
		
		Main.debugWindow.addMessage("Selected question: " + selectedQuestion);
		Main.debugWindow.addMessage(String.format("Volume: %s", begVol));
		
		loadCDCs();
	}

	private void loadCDCs() {
		questions = new ArrayList<Question>();
		try {
			InputStream stream = null;
			BufferedReader reader = null;
			
			if (file != null) {
		    	try {
					stream = new FileInputStream(file);
				} catch (FileNotFoundException e) {
					Main.debugWindow.addMessage(e.getMessage());
					e.printStackTrace();
					return;
				} catch (NullPointerException e) {
					Main.debugWindow.addMessage(e.getMessage());
					e.printStackTrace();
					return;
				}
		    }
		    else{
		    	try{
		    		stream = getClass().getResourceAsStream("/mil/cdc/data/cdcs/"+ selectedCDC + ".txt");
		    	} catch (NullPointerException e) {
					Main.debugWindow.addMessage(e.getMessage());
					e.printStackTrace();
					return;
		    	}
		    }
			reader = new BufferedReader(new InputStreamReader(stream));
			String line = "";
			
			while ((line = reader.readLine()) != null){
				lineNumber++;
				if (line.trim().equals("")) continue;
				
				String[] items = line.split(":");
				
				if (items.length != 6 && items.length != 2 && !items[0].startsWith("[")){
					Main.debugWindow.addMessage("Line # " + lineNumber +
                    " does not have enough parameters to add as a question\n\tSkipping...\n");
                continue;
				}
				
				if (volumeComboBox.getSelectedIndex() == 0) {
					volume = true;
				}
				else if (items[0].equals(begVol)) {
					volume = true;
				}
				else if (items[0].equals(endVol)) {
					volume = false;
				}
				
				if (!volume) continue;
				
				switch (selectedQuestion) {
				case 0:
					loadTest(items);
					loadReview(items);
					continue;
				case 1:
					loadTest(items);
					continue;
				case 2:
					loadReview(items);
					continue;
				default:
					loadTest(items);
					loadReview(items);
					continue;
				}
			}
			Main.debugWindow.addMessage("Done loading questions");
			numOfQuestions = numOfQuestions == 0? questions.size() : numOfQuestions;
			reader.close();
			this.dispose();
			mainWindow.startQuestions(questions, numOfQuestions);
		} catch (FileNotFoundException e) {
			Main.errorWindow.displayErrorMessage("File Not Found!");
			Main.debugWindow.addMessage("File not found!");
			e.printStackTrace();
		} catch (IOException e) {
			Main.errorWindow.displayErrorMessage("There was an issue opening the file");
			Main.debugWindow.addMessage("IO Exception");
			e.printStackTrace();
		}
	}

	private void loadReview(String[] items) {
		String question = items[0] + "?";
		ArrayList<String> choices = new ArrayList<String>();
		int answer = 0;
		if (items.length == 2){
			String item = items[1];
			item.trim();
			choices.add(item);
			for (int i = 0; i < 3; i++) {
				choices.add("None.");
			}
			
			answer = 1;
			Question currentQuestion = new Question(question.trim(), choices, 
					answer, rng.nextInt(Integer.MAX_VALUE));
			questions.add(currentQuestion);
		}
		
	}

	private void loadTest(String[] items) {
		 String question = items[0] + "?";
         ArrayList<String> choices = new ArrayList<String>();
         int answer = 0;
         if (items.length == 6)
         {
             for (int choicesIndex = 1; choicesIndex < 5; choicesIndex++)
             {
                 String item = items[choicesIndex];
                 item.trim();
                 choices.add(item + ".");
             }
             try
             {
                 answer = Integer.parseInt(items[5].trim());
             }
             catch (NumberFormatException ex)
             {
                 Main.debugWindow.addMessage("Error on Line " + lineNumber + ": answer is in the wrong format (must be numerical)\n"
                		 + "Value of answer was: " + items[5]);
                 return;
             }

             Question currentQuestion = new Question(question.trim(), choices, answer, rng.nextInt(Integer.MAX_VALUE));
             questions.add(currentQuestion); 
         }
	}	
	
	private void getVolumes() {
		volumeComboBox.removeAllItems();
		volumeComboBox.addItem("All Volumes");
		InputStream stream = null;
		BufferedReader reader = null;
		if (selectedCDC.toLowerCase().startsWith("custom")) {
			int returnVal = fc.showOpenDialog(this);
		
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				file = fc.getSelectedFile();
			}
			else {
				return;
			}
		}
		
	    if (file != null) {
	    	try {
				stream = new FileInputStream(file);
			} catch (FileNotFoundException e) {
				Main.debugWindow.addMessage(e.getMessage());
				e.printStackTrace();
				return;
			} catch (NullPointerException e) {
				Main.debugWindow.addMessage(e.getMessage());
				e.printStackTrace();
				return;
			}
	    }
	    else{
	    	try{
	    		stream = getClass().getResourceAsStream("/mil/cdc/data/cdcs/"+ selectedCDC + ".txt");
	    	} catch (NullPointerException e) {
				Main.debugWindow.addMessage(e.getMessage());
				e.printStackTrace();
				return;
	    	}
	    }
	    
	    reader = new BufferedReader(new InputStreamReader(stream));
		String line = "";
		int volume = 0;
		
		try {
			while ((line = reader.readLine())!= null){
				if (line.startsWith("[volume")){
					volumeComboBox.addItem("Volume " + ++volume);
				}
			}
		} catch (IOException e) {
			Main.debugWindow.addMessage("Unable to get volumes");
			e.printStackTrace();
		}

		
		
	}
}
